package middlewares

import (
	"context"
	"github.com/gin-gonic/gin"
	"strconv"
	"strings"

	"yundian/internel/app/logic"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
	. "yundian/internel/pkg/dingo/result"
	"yundian/internel/pkg/utils"
)

func JwtAuthMiddleware(ctx *gin.Context) {
	authHeader := ctx.Request.Header.Get("Access-Token")
	if authHeader == "" {
		Response(ctx)("token 错误", CodeNeedLogin, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 拆解token
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "dingo") {
		Response(ctx)("token 错误", CodeInvalidToken, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 解析token
	c, err := dingo.ParseToken(parts[1])
	if err != nil {
		Response(ctx)("token 解析失败"+err.Error(), CodeInvalidToken, nil)(Unauthorized) //
		ctx.Abort()
		return
	}

	// 验证token是否正确
	loginInfo := logic.NewAuthLogic().GetLoginInfoByPlatform(c.Platform, c.UserId)
	//key := utils.Join("YdLogin-Token", strconv.Itoa(c.UserId), t)
	token := global.Rdb.Get(context.Background(), loginInfo.TokenKey).Val()

	// 验证token是否过期
	ttlToken := global.Rdb.TTL(context.Background(), loginInfo.TokenKey).Val()
	if token == "" || ttlToken <= 0 {
		Response(ctx)("登录过期,请重新登录", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	if token != parts[1] {
		Response(ctx)("token 不正确", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	// 将token里的自定义信息保存在上下文context上
	ctx.Set("UserId", c.UserId)
	ctx.Set("UserName", c.UserName)
	ctx.Set("IsAdmin", c.IsAdmin)
	ctx.Set("ParentId", c.ParentId)
	ctx.Set("IsPlace", c.IsPlace)
	ctx.Set("IsDraw", c.IsDraw)
	ctx.Next()
}

// 微信小程序鉴权中间件
func JwtAppletAuthMiddleware(ctx *gin.Context) {
	authHeader := ctx.Request.Header.Get("Access-Token")
	if authHeader == "" {
		Response(ctx)("token 错误", CodeNeedLogin, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 拆解token
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "dingo") {
		Response(ctx)("token 错误", CodeInvalidToken, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 解析token
	c, err := dingo.ParseToken(parts[1])
	if err != nil {
		Response(ctx)("token 解析失败"+err.Error(), CodeInvalidToken, nil)(Unauthorized) //
		ctx.Abort()
		return
	}
	// 验证token是否正确
	key := utils.Join(global.Const.Pre.TokenKeyPre, "-Applet-Login-Token", c.UserName)
	token := global.Rdb.Get(context.Background(), key).Val()

	// 验证token是否过期
	ttlToken := global.Rdb.TTL(context.Background(), key).Val().Microseconds()
	if token == "" || ttlToken <= 0 {
		Response(ctx)("登录过期,请重新登录", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	if token != parts[1] {
		Response(ctx)("token 不正确", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	// 将token里的自定义信息保存在上下文context上
	ctx.Set("UserId", c.UserId)
	ctx.Set("UserName", c.UserName)
	ctx.Set("IsAdmin", c.IsAdmin)
	ctx.Set("ParentId", c.ParentId)
	ctx.Set("IsDraw", c.IsDraw)
	//ctx.Set("user_info", &dingo.CustomClaims{
	//	UserId:         c.UserId,
	//	UserName:       c.UserName,
	//	IsAdmin:        c.IsAdmin,
	//})
	ctx.Next()
}

// 微信公众号鉴权中间件
func JwtWechatAuthMiddleware(ctx *gin.Context) {
	authHeader := ctx.Request.Header.Get("Access-Token")
	if authHeader == "" {
		Response(ctx)("token 错误", CodeNeedLogin, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 拆解token
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "dingo") {
		Response(ctx)("token 错误", CodeInvalidToken, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	//log.Println("拆解token成功")
	// 解析token
	c, err := dingo.ParseToken(parts[1])
	if err != nil {
		Response(ctx)("token 解析失败"+err.Error(), CodeInvalidToken, nil)(Unauthorized) //
		ctx.Abort()
		return
	}
	//log.Println("解析token成功")
	// 验证token是否正确
	key := utils.Join("Yd-Wechat-Login-Token", strconv.Itoa(c.UserId))
	token := global.Rdb.Get(context.Background(), key).Val()

	// 验证token是否过期
	ttlToken := global.Rdb.TTL(context.Background(), key).Val().Microseconds()
	if token == "" || ttlToken <= 0 {
		Response(ctx)("登录过期,请重新登录", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}
	//log.Println("token未过期")

	if token != parts[1] {
		Response(ctx)("token 不正确", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	// 将token里的自定义信息保存在上下文context上
	ctx.Set("UserId", c.UserId)
	ctx.Set("UserName", c.UserName)
	ctx.Set("IsAdmin", c.IsAdmin)
	ctx.Set("ParentId", c.ParentId)
	ctx.Set("IsDraw", c.IsDraw)
	ctx.Set("IsPlace", c.IsPlace)
	//ctx.Set("user_info", &dingo.CustomClaims{
	//	UserId:         c.UserId,
	//	UserName:       c.UserName,
	//	IsAdmin:        c.IsAdmin,
	//})
	ctx.Next()
}

func JwtStewardAuthMiddleware(ctx *gin.Context) {
	authHeader := ctx.Request.Header.Get("Access-Token")
	if authHeader == "" {
		Response(ctx)("token 错误", CodeNeedLogin, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 拆解token
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "dingo") {
		Response(ctx)("token 错误", CodeInvalidToken, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	//log.Println("拆解token成功")
	// 解析token
	c, err := dingo.ParseToken(parts[1])
	if err != nil {
		Response(ctx)("token 解析失败"+err.Error(), CodeInvalidToken, nil)(Unauthorized) //
		ctx.Abort()
		return
	}
	//log.Println("解析token成功")
	// 验证token是否正确
	key := utils.Join("zm-steward-h5-Login-Token", strconv.Itoa(c.UserId))
	token := global.Rdb.Get(context.Background(), key).Val()

	// 验证token是否过期
	ttlToken := global.Rdb.TTL(context.Background(), key).Val().Microseconds()
	if token == "" || ttlToken <= 0 {
		Response(ctx)("登录过期,请重新登录", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}
	//log.Println("token未过期")

	if token != parts[1] {
		Response(ctx)("token 不正确", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	// 将token里的自定义信息保存在上下文context上
	ctx.Set("UserId", c.UserId)
	ctx.Set("UserName", c.UserName)
	ctx.Set("IsAdmin", c.IsAdmin)
	ctx.Set("ParentId", c.ParentId)
	ctx.Set("IsDraw", c.IsDraw)
	ctx.Set("IsPlace", c.IsPlace)
	ctx.Set("MessageTypes", c.MessageTypes)
	//ctx.Set("user_info", &dingo.CustomClaims{
	//	UserId:         c.UserId,
	//	UserName:       c.UserName,
	//	IsAdmin:        c.IsAdmin,
	//})
	ctx.Next()
}

// 支付宝小程序鉴权中间件
func JwtZfbAuthMiddleware(ctx *gin.Context) {
	authHeader := ctx.Request.Header.Get("Access-Token")
	if authHeader == "" {
		Response(ctx)("token 错误", CodeNeedLogin, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 拆解token
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "dingo") {
		Response(ctx)("token 错误", CodeInvalidToken, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 解析token
	c, err := dingo.ParseToken(parts[1])
	if err != nil {
		Response(ctx)("token 解析失败"+err.Error(), CodeInvalidToken, nil)(Unauthorized) //
		ctx.Abort()
		return
	}
	// 验证token是否正确
	key := utils.Join(global.Const.Pre.TokenKeyPre, "-Zfb-Login-Token", c.UserName)
	token := global.Rdb.Get(context.Background(), key).Val()

	// 验证token是否过期
	ttlToken := global.Rdb.TTL(context.Background(), key).Val().Microseconds()
	if token == "" || ttlToken <= 0 {
		Response(ctx)("登录过期,请重新登录", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	if token != parts[1] {
		Response(ctx)("token 不正确", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	// 将token里的自定义信息保存在上下文context上
	ctx.Set("UserId", c.UserId)
	ctx.Set("UserName", c.UserName)
	ctx.Set("IsAdmin", c.IsAdmin)
	ctx.Set("ParentId", c.ParentId)
	ctx.Set("IsDraw", c.IsDraw)
	//ctx.Set("user_info", &dingo.CustomClaims{
	//	UserId:         c.UserId,
	//	UserName:       c.UserName,
	//	IsAdmin:        c.IsAdmin,
	//})
	ctx.Next()
}

// wifi微信小程序
func JwtWifiAppletAuthMiddleware(ctx *gin.Context) {
	authHeader := ctx.Request.Header.Get("Access-Token")
	if authHeader == "" {
		Response(ctx)("token 错误", CodeNeedLogin, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 拆解token
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "dingo") {
		Response(ctx)("token 错误", CodeInvalidToken, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 解析token
	c, err := dingo.ParseToken(parts[1])
	if err != nil {
		Response(ctx)("token 解析失败"+err.Error(), CodeInvalidToken, nil)(Unauthorized) //
		ctx.Abort()
		return
	}
	// 验证token是否正确
	key := utils.Join(global.Const.Pre.TokenKeyPre, "-Wifi-Applet-Login-Token", c.UserName)
	token := global.Rdb.Get(context.Background(), key).Val()

	// 验证token是否过期
	ttlToken := global.Rdb.TTL(context.Background(), key).Val().Microseconds()
	if token == "" || ttlToken <= 0 {
		Response(ctx)("登录过期,请重新登录", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	if token != parts[1] {
		Response(ctx)("token 不正确", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	// 将token里的自定义信息保存在上下文context上
	ctx.Set("UserId", c.UserId)
	ctx.Set("UserName", c.UserName)
	ctx.Set("IsAdmin", c.IsAdmin)
	ctx.Set("ParentId", c.ParentId)
	ctx.Set("IsDraw", c.IsDraw)
	//ctx.Set("user_info", &dingo.CustomClaims{
	//	UserId:         c.UserId,
	//	UserName:       c.UserName,
	//	IsAdmin:        c.IsAdmin,
	//})
	ctx.Next()
}

func ZfbAgentJwtAuthMiddleware(ctx *gin.Context) {
	authHeader := ctx.Request.Header.Get("Access-Token")
	if authHeader == "" {
		Response(ctx)("token 错误", CodeNeedLogin, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 拆解token
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "dingo") {
		Response(ctx)("token 错误", CodeInvalidToken, nil)(Unauthorized) // 没有传token
		ctx.Abort()
		return
	}
	// 解析token
	c, err := dingo.ParseToken(parts[1])
	if err != nil {
		Response(ctx)("token 解析失败"+err.Error(), CodeInvalidToken, nil)(Unauthorized) //
		ctx.Abort()
		return
	}

	// 验证token是否正确
	key := utils.Join("Token", "-", "zfb", "-", "Login-Token-",strconv.Itoa(c.UserId))
	token := global.Rdb.Get(context.Background(), key).Val()

	// 验证token是否过期
	ttlToken := global.Rdb.TTL(context.Background(), key).Val()
	if token == "" || ttlToken <= 0 {
		Response(ctx)("登录过期,请重新登录", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	if token != parts[1] {
		Response(ctx)("token 不正确", CodeInvalidToken, nil)(Unauthorized)
		ctx.Abort()
		return
	}

	// 将token里的自定义信息保存在上下文context上
	ctx.Set("UserId", c.UserId)
	ctx.Set("UserName", c.UserName)
	ctx.Set("IsAdmin", c.IsAdmin)
	ctx.Set("ParentId", c.ParentId)
	ctx.Set("IsPlace", c.IsPlace)
	ctx.Set("IsDraw", c.IsDraw)
	ctx.Next()
}
